iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Security

我逆向你逆向我的逆向工程膩系列 第 10

Dx10 - 導入與導出函式位置表解析

  • 分享至 

  • xImage
  •  

IAT ( Import Address Table )

IAT 的內容與 windows 核心、記憶體、DLL 有關,它是一個表格,紀錄程序使用庫中的那些函數

IMAGE_IMPORT_DESCRIPTOR

IMPORT Directory Table,這個結構記錄 PE 檔案要引入那些 libary。並且位於 PE body 中 ( 不是 head ),但查找信息在 PE Head 裡面,詳細位於 IMAGE_OPTIONAL_HEADER.DataDirectory[1].VirtualAddress 就是 IMAGE_IMPORT_DESCRIPTOR 的起始位置。

winnt.h 的紀錄 :

https://ithelp.ithome.com.tw/upload/images/20220924/20135675eHrDlj1zAz.png

一個文件往往要導入多個 libary,要導入多少個 libary 決定於有多少個 IMAGE_IMPORT_DESCRIPTOR 結構,而這些結構組成一個 Table,這個 TableNULL(0x00) 來結束。

其中,IMAGE_IMPORT_DESCRIPTOR(IID) 的重要成員 :

  • OrigninalFirstThunk : INT ( Import name table ) 的位置 ( RVA )
  • Name : Libary 的名稱字串的位置 ( RVA )
  • FirstThunk : IAT ( Import address table ) 的位置 ( RVA )

下圖以 user32.dll 為範例 :

https://ithelp.ithome.com.tw/upload/images/20220924/20135675HLW0Ngsqew.png

輸入順序 :

  1. 讀取 IIDName 成員,取得字串 "USER32.DLL”
  2. LoadLibary(”USER32.DLL”);
  3. 讀取 OrigninalFirstThunk ,取得 INT 位置
  4. 使用 IMAGE_IMPORT_BY_NAMEHintName 取得函數得起始位置。
  5. 取得 IIDFirstThunk 成員值, 獲得 IAT 位置。
  6. 把函數位置輸入相應函數 IAT
  7. 重複 4~7 直到 IAT 位置指向值是 NULL

https://ithelp.ithome.com.tw/upload/images/20220924/20135675HlNgIwydQ8.png

使用 PE viewer 查看 Import Function :

https://ithelp.ithome.com.tw/upload/images/20220924/20135675qKtWIsxz5W.png

這個程式一開始是在 Win XP 環境上製成的,但在我的 Win 10 上也可以正常運行。這是因為 PE loader 在執行時會把位置改成相應 API 的起始位置。

EAT ( Export Data Table )

libary 是為了方便其他程式調用他的函式而集中有關函數的文件。像是 Win32 APIkernel32.dll 是最核心的庫文件。而 EAT 使其他程序可以透過 IMAGE_EXPORT_DIRECTORY 來得到這個文件的函數起始位置在哪裡,也只有使用這種方法才能取的 EAT 結構。

它的定義位置在於 _IMAGE_OPTIONAL_HEADER.DataDirectory[0].VirtualAddress,而定義於 winnt.h 中結構如下 :

https://ithelp.ithome.com.tw/upload/images/20220924/20135675h2G4fcIs8j.png

利用 PE bear 觀察結構在 kernel32.dll 中:

https://ithelp.ithome.com.tw/upload/images/20220924/20135675xuQl7Z78Lh.png

  • NumberOfNames : 輸出有名字的函數個數
  • Number of Function : 輸出函數個數
  • AddressOfFunction : 輸出的函數位置組數
  • AddressOfNames : 輸出函數名稱位置組數
  • AddressOfNameOrdinals : Ordinal 位置組數

以圖片為範例,看看程序上是甚麼從 Foo.DLL 中取得 AnotherExport ( 中間那一個函數 )的 :

  1. 利用 Address of name 取得名稱組
  2. 在名稱組中,透過比對 AnotherExport 字串來確認是否為需要的函數,結果為第二個。
  3. 透過 AddressOfNameOrdinals 的第二個取得 Ordinal 值為二 ( 有可能不是每次都是第二個,有些函數沒有名字會導致 Ordinal 值往後排 ) 。
  4. 利用 AddressOfFunctions 轉到 函數位置表 ( 也就是 EAT )。
  5. Ordinal 值作為索引,就可以取得函數的起始位置 !

https://ithelp.ithome.com.tw/upload/images/20220924/201356759D3rFvWvBG.png


上一篇
Dx09 - RAW & DLL
下一篇
Dx11 - 加殼時間
系列文
我逆向你逆向我的逆向工程膩31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言